﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Windows;
using System.ComponentModel;
using Windows.Storage;
using Windows.ApplicationModel;
using Newtonsoft.Json;
using System.Runtime.Serialization;
using System.Runtime;
using System.Linq;
namespace JiveMessenger.User
{
    public class AppSettings : INotifyPropertyChanged
    {
        ApplicationDataContainer _settings = ApplicationData.Current.LocalSettings;
        //  StorageFolder _localFolder 
        private static AppSettings _instance;
        public static AppSettings Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new AppSettings();
                    return _instance;
                }
                else
                    return _instance;
            }
        }
        // Our settings

        // The key names of our settings
        const string IsLockscreenDisabledSettingKeyName = "DisableLockscreenSetting";
        const string StoreMessagesWhileOfflineSettingKeyName = "StoreMessagesWhileOfflineSetting";
        //const string OfflineMessageAgeLimitSettingKeyName = "OfflineMessageAgeLimitSetting";
        //const string OfflineMessageCountLimitSettingKeyName = "OfflineMessageCountLimitSetting";
        const string IsOfflinePmToastEnabledSettingKeyName = "IsOfflinePmToastEnabledSetting";
        const string IsOfflineGroupToastEnabledSettingKeyName = "IsOfflineGroupToastEnabledSetting";
        const string CustomContactEmoticonsKeyName = "CustomContactEmoticons";
        const string CustomEmoticonsKeyName = "CustomEmoticons";
        const string ServerListSettingKeyName = "ServerListSetting";
        const string ServerSettingKeyName = "ServerSetting";
        const string UsernameSettingKeyName = "UsernameSetting";
        const string PushUriSettingKeyName = "PushUriSetting";
        const string ValidatedEmoticonsKeyName = "ValidatedEmoticons";
        //const string PasswordSettingKeyName = "PasswordSettings";
        const string EnableToastNotificationsKeyName = "EnableToastNotifications";
        const string EnableTileNotificationsKeyName = "EnableTileNotifications";
        const string HostnameCacheKeyName = "HostnameCache";
        const string RecentlyUsedDefaultEmoticonsKeyName = "RecentlyUsedDefaultEmoticons";
        const string RecentlyUsedCustomEmoticonsKeyName = "RecentlyUsedCustomEmoticons";
        const string LastOpenedEmoticonPageIndexKeyName = "LastOpenedEmoticonPageIndex";
        const string RequestedThemeKeyName = "RequestedTheme";
        //setting defaults
        const string ServerSettingDefault = "jiveMessenger.net";
        const string UsernameSettingDefault = "";
        const string PushUriSettingDefault = "";
        //const string PasswordSettingDefault = "";
        private string ServerListSettingDefault = "jiveMessenger.net";
        const string RequestedThemeDefault = "Dark";
        const bool EnableToastNotificationDefault = true;
        const bool EnableTileNotificationDefault = true;
        const bool IsLockscreenDisabledSettingDefault = false;
        const bool StoreMessagesWhileOfflineSettingDefault = true;
        const bool IsOfflineGroupToastEnabledSettingDefault = false;
        const bool IsOfflinePmToastEnabledSettingDefault = true;
        private Dictionary<string, string> HostnameCacheDefault = new Dictionary<string, string>();
        //const int OfflineMessageAgeLimitSettingDefault = 6;
        //const int OfflineMessageCountLimitSettingDefault = 150;
        private string RecentlyUsedDefaultEmoticonsDefault = "";
        private string RecentlyUsedCustomEmoticonsDefault = "";
        private string ValidatedEmoticonsDefault = "";
        private
        const int LastOpenedEmoticonPageIndexDefault = 0;
        /// <summary>
        /// Constructor that gets the application settings.
        /// </summary>
        private AppSettings()
        {
            // Get the settings for this application.
            if (!DesignMode.DesignModeEnabled)
            {
                //   _settings =ApplicationData.Current.LocalSettings;

                Debug.WriteLine("Created instance of AppSettings");
            }
        }
        //public static AppSettings GetInstance()
        //{
        //    if (_instance == null)
        //        return _instance = new AppSettings();
        //    else
        //        return _instance;
        //}
        #region INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
        /// <summary>
        /// Update a setting value for our application. If the setting does not
        /// exist, then add the setting.
        /// </summary>
        /// <param name="Key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool AddOrUpdateValue(string Key, Object value)
        {
            if (DesignMode.DesignModeEnabled)
                return false;

            bool valueChanged = false;

            // If the key exists
            if (_settings.Values.ContainsKey(Key))
            {
                // If the value has changed
                if (_settings.Values[Key] != value)
                {
                    // Store the new value
                    _settings.Values[Key] = value;
                    valueChanged = true;
                }
            }
            // Otherwise create the key.
            else
            {
                _settings.Values.Add(Key, value);
                valueChanged = true;
            }
            return valueChanged;
        }
        /// <summary>
        /// Get the current value of the setting, or if it is not found, set the 
        /// setting to the default setting.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public T GetValueOrDefault<T>(string Key, T defaultValue)
        {
            T value;

            // If the key exists, retrieve the value.
            if (_settings != null && _settings.Values.ContainsKey(Key))
            {

                value = (T)_settings.Values[Key];

            }
            // Otherwise, use the default value.
            else
            {
                value = defaultValue;
            }
            return value;
        }

        ///// <summary>
        ///// Save the settings.
        ///// </summary>
        //public void Save()
        //{
        //    settings.Values.Save();
        //}

        /// <summary>
        /// Property to get and set a Requested Theme Setting.
        /// </summary>
        public string RequestedThemeSetting
        {
            get
            {
                return GetValueOrDefault<string>(RequestedThemeKeyName, RequestedThemeDefault);
            }
            set
            {
                if (AddOrUpdateValue(RequestedThemeKeyName, value))
                {
                    RaisePropertyChanged("RequestedThemeSetting");
                }
            }
        }
        /// <summary>
        /// Property to get and set a Toast notification Setting.
        /// </summary>
        public bool IsToastNotificationEnabledSetting
        {
            get
            {
                return GetValueOrDefault<bool>(EnableToastNotificationsKeyName, EnableToastNotificationDefault);
            }
            set
            {
                if (AddOrUpdateValue(EnableToastNotificationsKeyName, value))
                {
                    RaisePropertyChanged("IsToastNotificationEnabledSetting");
                    //(App.Current as App).RegisterPush(true, (App.Current as App).AppSettings.IsToastNotificationEnabledSetting);
                }
            }
        }
        /// <summary>
        /// roperty to get and set disable lock screen setting.
        /// </summary>
        public bool IsLockscreenDisabledSetting
        {
            get
            {
                return GetValueOrDefault<bool>(IsLockscreenDisabledSettingKeyName, IsLockscreenDisabledSettingDefault);
            }
            set
            {
                if (AddOrUpdateValue(IsLockscreenDisabledSettingKeyName, value))
                {
                    RaisePropertyChanged("IsLockscreenDisabledSetting");
                    //App.SetLockscreenState(value);
                }
            }
        }

        /// <summary>
        /// Property to get and set a Tile notification Setting.
        /// </summary>
        public bool IsTileNotificationEnabledSetting
        {
            get
            {
                return GetValueOrDefault<bool>(EnableTileNotificationsKeyName, EnableTileNotificationDefault);
            }
            set
            {
                if (AddOrUpdateValue(EnableTileNotificationsKeyName, value))
                {
                    RaisePropertyChanged("IsTileNotificationEnabledSetting");
                    // (App.Current as App).RegisterPush(value, IsToastNotificationEnabledSetting);
                }
            }
        }

        /// <summary>
        /// Property to get and set a Server Setting.
        /// </summary>
        public string ServerSetting
        {
            get
            {
                return GetValueOrDefault<string>(ServerSettingKeyName, ServerSettingDefault);
            }
            set
            {
                if (AddOrUpdateValue(ServerSettingKeyName, value))
                {
                    RaisePropertyChanged("ServerSetting");
                }
            }
        }
        /// <summary>
        /// Property to get and set a Username Setting.
        /// </summary>
        public string UsernameSetting
        {
            get
            {
                return GetValueOrDefault<string>(UsernameSettingKeyName, UsernameSettingDefault);
            }
            set
            {
                if (AddOrUpdateValue(UsernameSettingKeyName, value))
                {
                    RaisePropertyChanged("UsernameSetting");
                }
            }
        }
        /// <summary>
        /// Property to get and set a Push Uri Setting.
        /// </summary>
        public string PushUriSetting
        {
            get
            {
                return GetValueOrDefault<string>(PushUriSettingKeyName, PushUriSettingDefault);
            }
            set
            {
                if (AddOrUpdateValue(PushUriSettingKeyName, value))
                {
                    RaisePropertyChanged("PushUriSetting");
                }
            }
        }
        ///// <summary>
        ///// Property to get and set a Password Setting.
        ///// </summary>
        //public string PasswordSetting
        //{
        //    get
        //    {
        //        return GetValueOrDefault<string>(PasswordSettingKeyName, PasswordSettingDefault);
        //    }
        //    set
        //    {
        //        if (AddOrUpdateValue(PasswordSettingKeyName, value))
        //        {

        //            RaisePropertyChanged("PasswordSetting");
        //        }
        //    }
        //}
        /// <summary>
        /// Property to get and set a Hostname Cache Setting.
        /// </summary>
        public Dictionary<string, string> HostnameCache
        {
            get
            {
                return GetValueOrDefault<Dictionary<string, string>>(HostnameCacheKeyName, HostnameCacheDefault);
            }
            set
            {
                if (AddOrUpdateValue(HostnameCacheKeyName, value))
                {
                    RaisePropertyChanged("HostnameCache");
                }
            }
        }
        ///// <summary>
        ///// Property to get and set a Hostname Cache Setting.
        ///// </summary>
        //public DateTime LastTaskRun
        //{
        //    get
        //    {
        //        return GetValueOrDefault<DateTime>(LastTaskRunSettingKeyName, LastTaskRunSettingDefault);
        //    }
        //    set
        //    {
        //        if (AddOrUpdateValue(LastTaskRunSettingKeyName, value))
        //        {
        //            Save();
        //        }
        //    }
        //}
        /// <summary>
        /// Property to get and set a server list Setting.
        /// </summary>
        public List<string> ServerListSetting
        {
            get
            {
                // return JsonConvert.DeserializeObject<List<string>>((string)GetValueOrDefault<string>(ServerListSettingKeyName, ServerListSettingDefault));
                return GetValueOrDefault<string>(ServerListSettingKeyName, ServerListSettingDefault).Split(',').ToList();
            }
            set
            {
                // var val = JsonConvert.SerializeObject(value);
                var val = string.Join(",", value);
                if (AddOrUpdateValue(ServerListSettingKeyName, val))
                {
                    RaisePropertyChanged("ServerListSetting");
                }
            }
        }


        //public bool StoreMessagesWhileOfflineSetting
        //{
        //    get
        //    {
        //        return GetValueOrDefault<bool>(StoreMessagesWhileOfflineSettingKeyName, StoreMessagesWhileOfflineSettingDefault);
        //    }
        //    set
        //    {
        //        if (AddOrUpdateValue(StoreMessagesWhileOfflineSettingKeyName, value))
        //        {
        //            RaisePropertyChanged("StoreMessagesWhileOfflineSetting");
        //        }
        //    }
        //}
        //public int OfflineMessageCountLimitSetting
        //{
        //    get
        //    {
        //        return GetValueOrDefault<int>(OfflineMessageCountLimitSettingKeyName, OfflineMessageCountLimitSettingDefault);
        //    }
        //    set
        //    {
        //        if (AddOrUpdateValue(OfflineMessageCountLimitSettingKeyName, value))
        //        {
        //            RaisePropertyChanged("OfflineMessageCountLimitSetting");
        //        }
        //    }
        //}
        //public int OfflineMessageAgeLimitSetting
        //{
        //    get
        //    {
        //        return GetValueOrDefault<int>(OfflineMessageAgeLimitSettingKeyName, OfflineMessageAgeLimitSettingDefault);
        //    }
        //    set
        //    {
        //        if (AddOrUpdateValue(OfflineMessageAgeLimitSettingKeyName, value))
        //        {
        //            RaisePropertyChanged("OfflineMessageAgeLimitSetting");
        //        }
        //    }
        //}
        public Dictionary<string, int> RecentlyUsedDefaultEmoticons
        {
            get
            {
                string storedVal = GetValueOrDefault<string>(RecentlyUsedDefaultEmoticonsKeyName, RecentlyUsedDefaultEmoticonsDefault);
                JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto };
                return JsonConvert.DeserializeObject<Dictionary<string, int>>(storedVal, settings) ?? new Dictionary<string, int>();
            }
            set
            {
                JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto };
                var val = JsonConvert.SerializeObject(value, settings);
                if (AddOrUpdateValue(RecentlyUsedDefaultEmoticonsKeyName, val))
                {
                    RaisePropertyChanged("RecentlyUsedDefaultEmoticons");
                }
            }
        }
        public List<string> ValidatedEmoticons
        {
            get
            {
                return GetValueOrDefault<string>(ValidatedEmoticonsKeyName, ValidatedEmoticonsDefault).Split(',').ToList();

                //JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All };
                //return JsonConvert.DeserializeObject<Dictionary<string, double>>(storedVal, settings) ?? new Dictionary<string, double>();
            }
            set
            {
                //JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All };
                //var val = JsonConvert.SerializeObject(value, settings);
                var val = string.Join(",", value);
                if (AddOrUpdateValue(ValidatedEmoticonsKeyName, val))
                {
                    RaisePropertyChanged("ValidatedEmoticons");
                }
            }
        }
        public Dictionary<string, int> RecentlyUsedCustomEmoticons
        {
            get
            {
                string storedVal = GetValueOrDefault<string>(RecentlyUsedCustomEmoticonsKeyName, RecentlyUsedCustomEmoticonsDefault);
                JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All };
                return JsonConvert.DeserializeObject<Dictionary<string, int>>(storedVal, settings) ?? new Dictionary<string, int>();
            }
            set
            {
                JsonSerializerSettings settings = new JsonSerializerSettings() { TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All };
                var val = JsonConvert.SerializeObject(value, settings);
                if (AddOrUpdateValue(RecentlyUsedCustomEmoticonsKeyName, val))
                {
                    RaisePropertyChanged("RecentlyUsedCustomEmoticons");
                }
            }
        }
        public int LastOpenedEmoticonPageIndex
        {
            get
            {
                return GetValueOrDefault<int>(LastOpenedEmoticonPageIndexKeyName, LastOpenedEmoticonPageIndexDefault);
            }
            set
            {
                if (AddOrUpdateValue(LastOpenedEmoticonPageIndexKeyName, value))
                {
                    RaisePropertyChanged("LastOpenedEmoticonPageIndex");
                }
            }
        }
        public bool OfflinePmToastEnabledSetting
        {
            get
            {
                return GetValueOrDefault<bool>(IsOfflinePmToastEnabledSettingKeyName, IsOfflinePmToastEnabledSettingDefault);
            }
            set
            {
                if (AddOrUpdateValue(IsOfflinePmToastEnabledSettingKeyName, value))
                {
                    RaisePropertyChanged(" OfflinePmToastEnabledSetting");
                }
            }
        }
        public bool OfflineGroupToastEnabledSetting
        {
            get
            {
                return GetValueOrDefault<bool>(IsOfflineGroupToastEnabledSettingKeyName, IsOfflineGroupToastEnabledSettingDefault);
            }
            set
            {
                if (AddOrUpdateValue(IsOfflineGroupToastEnabledSettingKeyName, value))
                {
                    RaisePropertyChanged("OfflineGroupToastEnabledSetting");
                }
            }
        }
    }
}
